package com.zx.dsptuneup_TriMic.Tools;

import com.zx.dsptuneup_TriMic.Util.ByteToString;
import java.math.BigInteger;
import java.util.HashMap;

/**
 * The type Number base conversion util.
 */
public class NumberBaseConversionUtil {

    /**
     * Value ten to value hex string.
     *
     * @param valueTen the value ten
     * @return the string
     * @ClassName: valueTenToValueHex(10进制转16进制)
     * @Description: 不保留前置0 ，如000000ff==ff
     * @date 2020年4月15日
     */
    public static String valueTenToValueHex(String valueTen){
		Integer value= Integer.parseInt(valueTen);
		return  Integer.toHexString(value);
	}

    /**
     * Value ten to value hex string.
     *
     * @param valueTen the value ten
     * @return the string
     * @ClassName: valueTenToValueHex(10进制转16进制)
     * @Description: 不保留前置0 ，如000000ff==ff
     * @date 2020年4月15日
     */
    public static String valueTenToValueHex(Integer valueTen){
		String v = valueTen+"";
		Integer value= Integer.parseInt(v);
		return  Integer.toHexString(value);
	}

    /**
     * Value ten to value hex str string.
     *
     * @param valueTen the value ten
     * @return the string
     * @ClassName: valueTenToValueHex(10进制转16进制)
     * @Description: 保留前置0 ，如000000ff
     * @date 2020年4月15日
     */
    public static String valueTenToValueHexStr(String valueTen){
		Integer value= Integer.parseInt(valueTen);
		return  String.format("%08x",value);
	}

    public static Integer valueHexToValueTenForComplement(String valueHex){
        Integer value = null;
        char ca = '1';
        String a = "FFFF";
        String substring = a.substring(0, 1);
        int ac = Integer.parseInt(substring, 16);
        if (ac < 8) {
            value = Integer.parseInt(a, 16);
        } else {
            int radix = 2;
            byte[] bytes = ByteToString.toByteArray(a);
            String string = new BigInteger(1, bytes).toString(radix);
            boolean isOk = true;
            if (ca == string.charAt(0)) {
                isOk = false;
            }
            int parseInt = Integer.parseInt(string, 2);
            // string.
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < string.length(); i++) {

                if (ca == string.charAt(i)) {
                    sb.append("0");
                } else {
                    sb.append("1");
                }
            }
            String afterStr = sb.toString();
            boolean f = false;
            String ss = "";
            for (int i = afterStr.length() - 1; i >= 0; i--) {
                if (!f) {
                    if (ca == afterStr.charAt(i)) {
                        ss = "0" + ss;
                    } else {
                        f = true;
                        ss = "1" + ss;
                    }
                } else {
                    ss = afterStr.charAt(i) + ss;
                }
            }
            parseInt = Integer.parseInt(ss, 2);
            if (!isOk) {
                parseInt = ~parseInt + 1;
            }
            value = parseInt;
        }
        return value;
    }

    /**
     * Value hex to value ten integer.
     *
     * @param valueHex the value hex
     * @return the integer
     * @ClassName: valueHexToValueTen(16进制转10进制)
     * @Description: 参数000000ff和ff都可以
     * @date 2020年4月15日
     */
    public static Integer valueHexToValueTen(String valueHex){
		Integer valueTen2 = Integer.parseInt(valueHex,16);
		return  valueTen2;
	}

    /**
     * Value two to value hex string.
     *
     * @param valueTwo the value two
     * @return the string
     * @ClassName: valueTwoToValueHex(2进制转16进制)
     * @Description: 参数000000ff和ff都可以
     * @date 2020年4月15日
     */
    public static String valueTwoToValueHex(String valueTwo){
		Integer valueTen2 = Integer.parseInt(valueTwo,2);
		String strHex = Integer.toHexString(valueTen2);
		return  strHex;
	}

    /**
     * [warning] 本协议专用
     * 10进制浮点小数(两位精度)转成16进制
     * 乘以100 eg: 12.31---1231   -5.32---- -532
     * 负号按照有符号字节传递 -10 == 0x8000|0x0A00
     *
     * @param num the number
     * @return the string
     */
    public static String tenDecimalToSixTeen(double num) {
        int number = (int) (100 * num);

        if (number < 0 ){
            int temp = number;
            temp =  Math.abs(number);
            temp = temp|0x8000;
            return TenToSix(temp);
        }else{
            //  10进制转16进制
            return TenValueToHexUtils.TenToHexAndAppendZeroTo4(number);
        }

    }



    /**
     * 10进制转16进制
     * 负数 高位取1，转16进制补两位
     * @param number the number
     * @return the string
     */
    public static String TenToSix(int number) {
        if (number < 0 ){
            int temp = number;
            temp =  Math.abs(number);
            temp = temp|0x8000;
            return TenToSix(temp);
        }else{
            //  10进制转16进制
            return TenValueToHexUtils.TenToHexAndAppendZeroTo2(number);
        }
    }

	private static String getValueTwo(double d) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < 24; i++) {
			d = d*2;
			sb.append((int)d%2);
		}
		return sb.toString();
	}


	/************************** 16进制转10进制 反向赋值用于获取数据显示 ***********************************************/
    /**
     * 正常16进制转10进制整数 u8,u16 ----int 不带符号
     * */
    public static int NormalSixToTen(String number) {
        int x = Integer.parseInt(number,16);
        return x;
    }

	/**
     * 16进制转10进制整数  带符号
     * */
    public static int SixToTen(String number) {
        //  先转为2进制
        String two = SixToTwo(number);
        return binTodec(two);
    }

    /**
     * Six to decimal ten int.
     *  16进制转10进制小数 (注意除100)
     * @param number the number
     * @return the int
     */
    public static double SixToDecimalTen(String number) {
        //  先转为2进制
        String two = SixToTwo(number);
        return Double.valueOf(binTodec(two))/100;
    }

    /**
     *  负数小数，不通用，根据本协议传
     *  整数部分和小数用，分割
     *  整数部分按补码 一个字节 小数部分转16进制
     * */
//    public static String tenDecimalToSixTeen(double number) {
//        String sixTeen = "";
//        int intPart =  (int)number;
//        double decPart = number - intPart + 1;
//        decPart = decPart -  Math.floor(decPart);
//        if (number > 0) {
//            String intPartComplement = DecTenToSix((int)intPart);
//            sixTeen = sixTeen + intPartComplement ;
//        }else{
//            double intPartComplement = 0xFF - Math.abs(intPart);
////            let intPartComplement =  TenToSix(number: abs(Int(number)))
//            sixTeen = sixTeen + DecTenToSix((int)intPartComplement);
//        }
//
//        double tenNew = decPart; // 新
//        int    sixInt = 0;
//        double tenDouble = 0;
//        for (int i = 0;i<6;i++){   /*由于协议中需要传的是六位*/
//            sixInt =  (int) Math.floor(tenNew * 16);
//            tenDouble = tenNew * 16;
//            sixTeen += decTohex(sixInt);
//            tenNew = tenDouble - (double)sixInt;
//        }
//        //十六进制h转二进制
//        return sixTeen;
//    }

    /**
     * 4个字节
     * 16进制转10进制小数(浮点型)
     * "FE38E152"
     **/
//    public static String sixToDecimalTen(String hexStr) {
//        double tenInt = 0;
//        // 取整数位
//
//        boolean isNegative = false;
//        String intPart = hexStr.substring(0,2);
//        if(SixToTen(intPart) > 0x80){  // 说明是负数
//            tenInt +=  0xFF - SixToTen(intPart);
//            isNegative = true;
//        }else {
//            isNegative = false;
//        }
//
//        //  处理小数部分
//        double tempDeci = 0;
//        for (int i = 2;i<8;i++){   /*由于协议中需要传的是六位*/
//            String decPart = hexStr.substring(i,i+1);
//            int tempInt = SixToTen(decPart);
//
//            double base = Math.pow(16, i-1);  //  几个16，16 的n次方
//            tempDeci += ((double)tempInt)/(base);
//        }
//
//        if(isNegative){
//            tenInt += (1- tempDeci);
//            return "-" + tenInt;
//        }else {
//            tenInt += tempDeci;
//            return tenInt+"";
//        }
//    }

    public static String DecTenToSix(int number) {
        if (number < 0 ){
            int temp = number;
            temp =  Math.abs(number);
            temp = temp|0x80;
            return DecTenToSix(temp);
        }else{
            //  10进制转16进制
            return TenValueToHexUtils.TenToHexAndAppendZeroTo2(number);
        }
    }


    public static String decTohex(int number) {
        return Integer.toHexString(number).toUpperCase();
    }


    /**
     * warnning !!!!数据很小的情况下（max/2）适用，否则不通用
     *
     十六进制转换为二进制
     @param hex 十六进制数
     @return 二进制数
     */
    private static String SixToTwo(String hex) {
        //  s注意若是8，则代表负数，1000转为0000
        HashMap<String, String> hexDic = new HashMap<>();
        hexDic.put("0","0000");
        hexDic.put("1","0001");
        hexDic.put("2","0010");
        hexDic.put("3","0011");
        hexDic.put("4","0100");
        hexDic.put("5","0101");
        hexDic.put("6","0110");
        hexDic.put("7","0111");
        hexDic.put("8","1000");
        hexDic.put("9","1001");
        hexDic.put("A","1010");
        hexDic.put("B","1011");
        hexDic.put("C","1100");
        hexDic.put("D","1101");
        hexDic.put("E","1110");
        hexDic.put("F","1111");


        int count =  hex.length();

        String binary = "";
        for (int index = 0; index < hex.length(); index++) {
            String key = hex.substring(index,index+1);
            String value = hexDic.get(key.toUpperCase());
//            if (hex.length() > 1 & index == 0 & key.equals("8")) {

            if (hex.length() > 1 & index == 0 & Integer.parseInt(key, 16)>=8 ) {
                //  符号位1----转为0
                value = changeUnsigned(value);
                value = "-" + value;
            }

            if (value != null) {
                binary = binary + value;
            }
        }
        return binary;
    }
    private static String changeUnsigned(String str){
        String returnStr = "";
        if (str.length()==4){
            for(int i=0;i<4;i++){
                if(i==0){
                    returnStr+="0";
                }else {
                    returnStr+=str.substring(i,i+1);
                }

            }
        }
        return returnStr;
    }


    /// 二进制转十进制
    /// - Parameter num: 负数包含-
    private static int binTodec(String num) {
        String temp1 = num;
        boolean flag  = num.contains("-");
        if (flag) {
            temp1 = temp1.replace("-", "");
        }

        int sum = 0;
        char[] c = temp1.toCharArray();

        for(char cc:c){
            String str =  String.valueOf(cc);
            sum = sum * 2 + Integer.valueOf(str).intValue();
        }
        return flag ?  -sum : sum;
    }






}
